JVM面试题及答案(2023版最全总结) – mikechen | 您所在的位置:网站首页 › mat 内存大小 › JVM面试题及答案(2023版最全总结) – mikechen |
JVM面试题是Java面试经常考察的内容,下面给大家总结一份非常全面的JVM面试题及答案@mikechen 目录 JVM是什么JVM,全称是Java虚拟机,是Java编程语言的运行环境,它可以在不同的操作系统上运行Java程序。 Java虚拟机屏蔽了与具体操作系统平台相关的信息,使得Java程序只需生成在Java虚拟机上运行的目标代码字节码。 如下图所示: 简单来说JVM是用来解析和运行Java程序的,它是Java平台的核心组件,提供了许多功能,例如垃圾回收、内存管理、安全性和线程管理等。 JVM内存模型 JVM内存模型的整体结构,如下图所示: 包含:JVM堆、虚拟机栈、程序计数器、Java方法区、本地方法栈。 1.JVM堆(Heap) 它是Java虚拟机中最大的一块内存区域,用于存储对象实例和数组,堆是所有线程共享的,因此在多线程环境下需要注意并发访问的问题。
2.JVM方法区(Method Area) 它是所有线程共享的内存区域,用于存储已加载的类信息、常量、静态变量、即时编译器编译后的代码等。 方法区也称为永久代(PermGen),但在JDK8之后,永久代已被移除,被元空间(MetaSpace)所代替。
3.Java虚拟机栈(Java Virtual Machine Stacks) 用于存储方法的局部变量、操作数栈、动态链接、方法出口等信息。栈帧在方法执行结束后会被弹出。
4.程序计数器(Program Counter Register) 它是一块较小的内存区域,用于存储正在执行的Java虚拟机字节码指令的地址。
5.本地方法栈(Native Method Stacks) 它用于存储Java程序调用本地方法(Native Method)时的参数和返回值。 JVM垃圾回收算法 1.标记清除算法 如下图所示: 1.标记阶段 从程序的根对象开始,递归遍历所有可以到达的对象,并将它们标记为“可达”的对象。
2.清除阶段 遍历整个堆,将没有标记的对象,即未被标记为“可达”,视为垃圾并回收其占用的内存。
标记清除算法适用 标记清除算法适用于:存活对象较多的情况,比较适用于年老代。
2.复制算法 复制算法,如下图所示: 复制算法步骤,主要分为如下步骤: 第一步:标记出所有的存活对象 从根集合节点进行扫描,例如:线程栈中的对象、静态变量、寄存器中的指针等,标记出所有的存活对象,
第二步:复制对象到新内存 找出所有仍然存活的对象,并将这些存活的对象复制到一块儿新的内存,比如:上方图片下边的那一块儿绿色内存。
第三步:回收垃圾并被清除 当所有存活的对象都被复制到To区后,From区中的所有对象都可以被清除(图中上边的那一块儿内存)。
复制算法适合 复制算法适合存活对象较少的情况下比较高效,基本上98%的对象是”朝生夕死”的,存活下来的会很少,所以特别适合于新生代。
3.标记整理算法 如下图所示: 标记整理算法步骤,主要分为如下4个步骤: 遍历内存中的所有对象,标记出所有正在使用的对象。 将所有标记过的对象移动到内存的一端,形成一个连续的内存块,同时将这些对象的地址更新到新的位置上。 将内存块另一端的所有未标记对象删除,并将这些内存空间标记为可用。 更新所有指向移动对象的指针,使其指向新的地址。
标记整理算法适合 标记整理算法适合老年代进行垃圾收集,parallel Oldgc和Serial old收集器就是采用该算法进行回收的。
4.分代收集算法 分代收集算法就是目前虚拟机使用的回收算法,这种算法根据对象的存活周期的不同将内存划分成几块,新生代和老年代,这样就可以根据各个年代的特点采用最适当的收集算法。 JVM垃圾收集器 1.Serial串行收集器 Serial是一个新生代收集器,使用的是标记复制算法,Serial收集器是最基础也是历史最悠久的收集器。 如下图所示: Serial串行收集器的主要特点是单线程收集,即只使用一个线程来完成垃圾收集工作,它使用标记复制算法进行垃圾回收。
2.Parallel并行收集器 Parallel并行收集器是在Serial收集器的基础上发展而来,如下图所示: 其主要特点是使用多个线程同时进行垃圾回收,从而提高垃圾回收的效率,它使用标记复制算法进行垃圾回收。
3.CMS收集器 CMS收集器,全称是Concurrent Mark Sweep,CMS收集器主要用于收集老年代的垃圾。 如下图所示: 相比于Serial和Parallel收集器,CMS收集器的主要特点是采用并发收集的方式,,采用的是标记清除算法。
4.G1收集器 G1垃圾收集器全称是Garbage First,G1垃圾收集器采用的是分代收集的思想。 如下图所示: 它将整个Java堆内存划分为多个大小相等的区域(Region),每个区域可以是年轻代,也可以是老年代。 G1收集器的阶段分以下几个步骤: 5.ZGC垃圾收集器 ZGC也称为The Z Garbage Collector,ZGC垃圾收集器是JDK 11中推出的一款追求极致低延迟的性质的JVM垃圾收集器。 与CMS中的ParNew和G1类似,ZGC也采用标记复制算法,不过ZGC对该算法做了重大改进。
6.Shenandoah垃圾收集器 Shenandoah垃圾收集器于JDK 12中首次引入,主要针对需要大内存和低延迟的应用场景。 JVM调优参数 以下是重要的JVM调优参数: 1.指定JVM的初始内存和最大内存 参数: -Xms和-Xmx示例: -Xms512m -Xmx2g指定JVM的初始内存为512MB,最大内存为2GB。
2.设置新生代的内存大小 参数: -Xmn示例: -Xmn2gXmn2g:设置年轻代大小为2G。
3.指定持久代的初始大小和最大大小 参数: -XX:PermSize和-XX:MaxPermSize示例: -XX:PermSize=128m -XX:MaxPermSize=256m指定持久代的初始大小为128MB,最大大小为256MB。
4.启用G1垃圾收集器 参数: -XX:+UseG1GC示例: java -XX:+UseG1GC Main启用G1垃圾收集器。
5.启用CMS垃圾收集器 参数: -XX:+UseConcMarkSweepGCUseConcMarkSweepGC,表示启用CMS垃圾收集器。
6.打印垃圾收集器的详细信息和时间戳 参数: -XX:+PrintGCDetails参数: -XX:+PrintGCDetails -XX:+PrintGCDateStamps打印垃圾收集器的详细信息和时间戳。
7.调整新生代和老年代的比例 参数: -XX:NewRatio=2NewRatio=2表示新生代和老年代的比例为1:2。
8.调整Eden区和Survivor区的比例 参数: -XX:SurvivorRatio=8SurvivorRatio=8表示Eden区和Survivor区的比例为8:1。 JVM性能调优 JVM性能调优主要包含以下方法,大概分为5个步骤: 1.监控GC的状态 使用各种JVM调优工具,查看当前日志,分析当前JVM调优参数设置,并且分析当前堆内存快照和gc日志。 根据实际的各区域内存划分和GC执行时间,觉得是否进行优化。 举一个例子: 系统崩溃前的一些现象: 每次垃圾回收的时间越来越长; FullGC的次数越来越多; 逐渐到达OutOfMemoryError的临界值;这个时候就需要分析JVM内存快照dump。 2.生成堆的dump文件 可以通过Java的jmap命令来生成该文件,需要分析dump文件。
3.分析dump文件 打开这个3G的堆信息文件,显然一般的Window系统没有这么大的内存,必须借助高配置的Linux,几种工具打开该文件: Visual VM; MAT; JDK 自带的Hprof工具等;文件太大,建议使用Eclipse专门的静态内存分析工具Mat打开分析。
4.分析和调整 这里会涉及到如下内容: 调整垃圾回收机制,提高垃圾回收效率,避免长时间的停顿; 调整线程池大小,避免线程过多导致的性能下降; 优化代码,减少不必要的对象创建和内存占用等。
5.不断的试验和试错 最后,就需要通过不断的试验和试错,分析并找到最合适的参数,并则将这些参数应用到所有服务器。 以上就是JVM面试题及答案详解,更多JVM内容请查看:JVM(Java虚拟机)从0到1全部合集 以上! 关注作者「mikechen」公众号,获取更多架构面试干货! 关注公众号回复【架构】,即可获取《阿里架构师进阶从0到1全部合集》,回复【面试】即可获取《1000+大厂面试题及答案》 |
CopyRight 2018-2019 实验室设备网 版权所有 |